/*
fifo_port_uart u_fifo_port_uart_0(
       .clk50M(clk50M),
		 .rst_n(rst_n),
		 .data(dc_fifo_q_w),
		 .write(wr_fifo_wr_w),
		 .wr_full(wr_fifo_full_w),
		 .rd_empty(rx_fifo_empty_w),
		 .read(rx_fifo_rd_w),
		 .q(rx_fifo_q_w),
		 .uart_rxd(uart_rxd),
		 .uart_txd(uart_txd)
);
*/
module fifo_port_uart(
       input        clk50M,
		 input        rst_n,
		 input [7:0]  data,
		 input        write,
		 output       wr_full,
		 output       rd_empty,
		 input        read,
		 output [7:0] q,
		 input        uart_rxd,
		 output       uart_txd
);
precise_divider
#(
	//DEVIDE_CNT = 85.89934592 * fo
	.DEVIDE_CNT(32'd351843721)	//256000bps * 16
//	parameter		DEVIDE_CNT = 32'd175921860	//128000bps * 16
//	.DEVIDE_CNT(32'd158329674)                //115200bps * 16
//   .DEVIDE_CNT(32'd13194140)	//9600bps * 16
)
precise_divider_u
(
	//global clock
	.clk(clk50M),
	.rst_n(rst_n),
	
	//user interface
	//.divide_clk(),
	.divide_clken(clken_16bps)
);
wire [7:0] txfifo_q_w;
wire       txfifo_rd_w,txfifo_empty_w;
uart_txfifo txfifo (
	.aclr(~rst_n),
	.clock(clk50M),
	.data(data),
	.rdreq(txfifo_rd_w),
	.wrreq(write),
	.almost_full(wr_full),
	.empty(txfifo_empty_w),
	.q(txfifo_q_w)
	);
wire clken_16bps,txd_flag_w;
wire txd_en_w;
assign txd_en_w = txfifo_rd_r;
uart_transfer uart_transfer_u(
	 .clk(clk50M),
	 .rst_n(rst_n),
	 .clken_16bps(clken_16bps),
	 .txd(uart_txd),		
	 .txd_en(txd_en_w),		
    .txd_data(txfifo_q_w),
	 .txd_flag(txd_flag_w)
	 );
wire rxd_flag_w;
wire [7:0] rxd_data_w;
uart_receiver uart_receiver_u(//gobal clock
	.clk(clk50M),
	.rst_n(rst_n),
	.clken_16bps(clken_16bps),
	.rxd(uart_rxd),
	.rxd_flag(rxd_flag_w),
	.rxd_data(rxd_data_w)	
	               	);
uart_txfifo rxfifo (
	.aclr(~rst_n),
	.clock(clk50M),
	.data(rxd_data_w),
	.rdreq(read),
	.wrreq(rxd_flag_w),
	.almost_full(),
	.empty(rd_empty),
	.q(q)
	);
reg tx_state;
reg txfifo_rd_r;
assign txfifo_rd_w= (~txfifo_empty_w) & (~tx_state);
always@(posedge clk50M or negedge rst_n)
begin
if(!rst_n)
    begin
	 tx_state    <= 1'b0;
	 txfifo_rd_r <= 1'b0;
	 end
else
    begin
	 txfifo_rd_r   <= txfifo_rd_w;
	 case(tx_state)
	 1'b0:tx_state <= txfifo_empty_w?tx_state:1'b1;
	 1'b1:tx_state <= txd_flag_w?1'b0:tx_state;
	 endcase
	 end
end
endmodule 